#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
class Dot;
class CirCle;
class Rectangle;
class CompoundShape;

class Visitor
{
public:
    virtual void visitDot(Dot* d) = 0;
    virtual void visitCirCle(CirCle* d) = 0;
    virtual void visitRectangle(Rectangle* d) = 0;
    virtual void visitCompoundShape(CompoundShape* d) = 0;

};

class Shape
{
public:
    virtual void move(int x, int y) = 0;
    virtual void draw() = 0;
    virtual void accept(Visitor *v) = 0;
};

class Dot : public Shape
{
public:
    int x,y;
    Dot(int x_, int y_):x(x_),y(y_){};
    void move(int x, int y)
    {

    }
    void draw()
    {

    }
    void accept(Visitor *v)
    {
        v->visitDot(this);
    }
};

class CirCle : public Shape
{
public:
    int x,y,r;
    CirCle(int x_, int y_, int r_):x(x_),y(y_),r(r_){};
    void move(int x, int y)
    {

    }
    void draw()
    {

    }
    void accept(Visitor *v)
    {
        v->visitCirCle(this);
    }
};


class Rectangle : public Shape
{
public:
    int x,y,w,h;
    Rectangle(int x_, int y_, int w_, int h_):x(x_),y(y_),w(w_),h(h_){};
    void move(int x, int y)
    {

    }
    void draw()
    {

    }
    void accept(Visitor *v)
    {
        v->visitRectangle(this);
    }
};


class CompoundShape : public Shape
{
public:
    void move(int x, int y)
    {

    }
    void draw()
    {

    }
    void accept(Visitor *v)
    {
        v->visitCompoundShape(this);
    }
};

class XMLExportVisitor : public Visitor
{
    void visitDot(Dot* d)
    {
        std::cout<<"Dot ("<<d->x<<","<<d->y<<")"<<std::endl;
    }
    void visitCirCle(CirCle* d)
    {
        std::cout<<"CirCle ("<<d->x<<","<<d->y<<","<<d->r<<")"<<std::endl;
    }
    void visitRectangle(Rectangle* d)
    {
        std::cout<<"Rectangle ("<<d->x<<","<<d->y<<","<<d->w<<","<<d->h<<")"<<std::endl;
    }
    void visitCompoundShape(CompoundShape* d)
    {
    }
};
int main() {
    XMLExportVisitor* exportVisitor = new XMLExportVisitor();
    std::vector<Shape*> list;
    list.push_back(new Dot(1,1));
    list.push_back(new CirCle(1,1, 2));
    list.push_back(new Rectangle(1,1,2,2));
    for(auto c : list)
        c->accept(exportVisitor);
    return 0;
}




